package com.ruoyi.restaurant.service.impl;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.restaurant.domain.Order;
import com.ruoyi.restaurant.domain.OrderDetail;
import com.ruoyi.restaurant.mapper.OrderMapper;
import com.ruoyi.restaurant.mapper.RestMenuMapper;
import com.ruoyi.restaurant.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 订单Service业务层处理
 *
 * @author ruoyi
 */
@Service
public class OrderServiceImpl implements IOrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private RestMenuMapper menuMapper;

    /**
     * 查询订单列表
     *
     * @param order 订单信息
     * @return 订单集合
     */
    @Override
    public List<Order> selectOrderList(Order order) {
        return orderMapper.selectOrderList(order);
    }

    /**
     * 根据ID查询订单
     *
     * @param id 订单ID
     * @return 订单信息
     */
    @Override
    public Order selectOrderById(Long id) {
        Order order = orderMapper.selectOrderById(id);
        if (order != null) {
            List<OrderDetail> orderDetails = orderMapper.selectOrderDetailList(id);
            order.setOrderDetails(orderDetails);
        }
        return order;
    }

    /**
     * 根据餐台ID查询进行中的订单
     *
     * @param tableId 餐台ID
     * @return 订单信息
     */
    @Override
    public Order selectOrderByTableId(Long tableId) {
        Order order = orderMapper.selectOrderByTableId(tableId);
        if (order != null) {
            List<OrderDetail> orderDetails = orderMapper.selectOrderDetailList(order.getId());
            order.setOrderDetails(orderDetails);
        }
        return order;
    }

    /**
     * 新增订单
     *
     * @param order 订单信息
     * @return 结果
     */
    @Override
    public int insertOrder(Order order) {
        order.setCreateTime(DateUtils.getNowDate());
        return orderMapper.insertOrder(order);
    }

    /**
     * 修改订单
     *
     * @param order 订单信息
     * @return 结果
     */
    @Override
    public int updateOrder(Order order) {
        order.setUpdateTime(DateUtils.getNowDate());
        return orderMapper.updateOrder(order);
    }

    /**
     * 删除订单
     *
     * @param id 订单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteOrderById(Long id) {
        // 先删除订单明细
        orderMapper.deleteOrderDetailByOrderId(id);
        // 再删除订单
        return orderMapper.deleteOrderById(id);
    }

    /**
     * 批量删除订单
     *
     * @param ids 需要删除的订单ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteOrderByIds(Long[] ids) {
        for (Long id : ids) {
            orderMapper.deleteOrderDetailByOrderId(id);
        }
        return orderMapper.deleteOrderByIds(ids);
    }

    /**
     * 点单（创建订单并添加菜品）
     *
     * @param order 订单信息（包含订单明细）
     * @return 结果
     */
    @Override
    @Transactional
    public int placeOrder(Order order) {
        // 生成订单号
        String orderNumber = generateOrderNumber();
        order.setOrderNumber(orderNumber);
        order.setStatus("0"); // 进行中
        order.setTotalAmount(BigDecimal.ZERO);
        order.setCreateTime(DateUtils.getNowDate());

        // 插入订单
        int result = orderMapper.insertOrder(order);
        if (result > 0 && order.getOrderDetails() != null && !order.getOrderDetails().isEmpty()) {
            // 计算总金额并插入订单明细
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (OrderDetail detail : order.getOrderDetails()) {
                detail.setOrderId(order.getId());
                // 计算小计
                BigDecimal subtotal = detail.getPrice().multiply(new BigDecimal(detail.getQuantity()));
                detail.setSubtotal(subtotal);
                totalAmount = totalAmount.add(subtotal);

                // 扣减库存（餐位费的menuId为0，不扣减库存）
                if (detail.getMenuId() != null && detail.getMenuId() > 0) {
                    int stockResult = menuMapper.decreaseStock(detail.getMenuId(), detail.getQuantity());
                    if (stockResult == 0) {
                        throw new ServiceException("菜品【" + detail.getMenuName() + "】库存不足");
                    }
                }
            }
            // 批量插入订单明细
            orderMapper.batchInsertOrderDetail(order.getOrderDetails());
            // 更新订单总金额
            order.setTotalAmount(totalAmount);
            orderMapper.updateOrder(order);
        }
        return result;
    }

    /**
     * 加单（向现有订单添加菜品）
     *
     * @param orderDetails 订单明细列表
     * @return 结果
     */
    @Override
    @Transactional
    public int addOrderItems(List<OrderDetail> orderDetails) {
        if (orderDetails == null || orderDetails.isEmpty()) {
            throw new ServiceException("订单明细不能为空");
        }

        Long orderId = orderDetails.get(0).getOrderId();
        Order order = orderMapper.selectOrderById(orderId);
        if (order == null) {
            throw new ServiceException("订单不存在");
        }
        if ("1".equals(order.getStatus())) {
            throw new ServiceException("订单已结账，无法加单");
        }

        // 计算新增金额并扣减库存
        BigDecimal addAmount = BigDecimal.ZERO;
        for (OrderDetail detail : orderDetails) {
            detail.setOrderId(orderId);
            // 计算小计
            BigDecimal subtotal = detail.getPrice().multiply(new BigDecimal(detail.getQuantity()));
            detail.setSubtotal(subtotal);
            addAmount = addAmount.add(subtotal);

            // 扣减库存（餐位费的menuId为0，不扣减库存）
            if (detail.getMenuId() != null && detail.getMenuId() > 0) {
                int stockResult = menuMapper.decreaseStock(detail.getMenuId(), detail.getQuantity());
                if (stockResult == 0) {
                    throw new ServiceException("菜品【" + detail.getMenuName() + "】库存不足");
                }
            }
        }

        // 批量插入订单明细
        int result = orderMapper.batchInsertOrderDetail(orderDetails);

        // 更新订单总金额
        if (result > 0) {
            BigDecimal newTotalAmount = order.getTotalAmount().add(addAmount);
            order.setTotalAmount(newTotalAmount);
            orderMapper.updateOrder(order);
        }

        return result;
    }

    /**
     * 查询订单明细
     *
     * @param orderId 订单ID
     * @return 订单明细列表
     */
    @Override
    public List<OrderDetail> selectOrderDetailList(Long orderId) {
        return orderMapper.selectOrderDetailList(orderId);
    }

    /**
     * 结账
     *
     * @param order 订单信息（包含原始金额、优惠金额、实收金额）
     * @return 结果
     */
    @Override
    @Transactional
    public int checkout(Order order) {
        Order existingOrder = orderMapper.selectOrderById(order.getId());
        if (existingOrder == null) {
            throw new ServiceException("订单不存在");
        }
        if ("1".equals(existingOrder.getStatus())) {
            throw new ServiceException("订单已结账");
        }

        // 设置结账信息
        existingOrder.setStatus("1"); // 已结账
        existingOrder.setCheckoutTime(DateUtils.getNowDate());
        existingOrder.setOriginalAmount(order.getOriginalAmount()); // 原始金额
        existingOrder.setDiscountAmount(order.getDiscountAmount()); // 优惠金额
        existingOrder.setActualAmount(order.getActualAmount()); // 实收金额

        return orderMapper.updateOrder(existingOrder);
    }

    /**
     * 查询已结账订单列表（按日期过滤）
     *
     * @param order 订单信息（包含日期范围）
     * @return 已结账订单列表
     */
    @Override
    public List<Order> selectCheckedOutOrderList(Order order) {
        // 设置状态为已结账
        order.setStatus("1");
        return orderMapper.selectOrderList(order);
    }

    /**
     * 查询订单详情（包含订单明细和菜品信息）
     *
     * @param orderId 订单ID
     * @return 订单详情（包含明细列表）
     */
    @Override
    public Order selectOrderDetailById(Long orderId) {
        // 查询订单基本信息
        Order order = orderMapper.selectOrderById(orderId);
        if (order != null) {
            // 查询订单明细
            List<OrderDetail> orderDetails = orderMapper.selectOrderDetailList(orderId);
            order.setOrderDetails(orderDetails);
        }
        return order;
    }

    /**
     * 查询待出餐菜品（按餐品类型筛选）
     *
     * @param categoryType 餐品类型（前厅/后厨/吧台）
     * @return 待出餐菜品列表
     */
    @Override
    public List<java.util.Map<String, Object>> selectPendingKitchenItems(String categoryType) {
        return orderMapper.selectPendingKitchenItems(categoryType);
    }

    /**
     * 按订单分组查询待出餐菜品（用于出餐中心，根据用户权限筛选）
     *
     * @param categoryTypes 餐品类型列表（根据用户权限筛选）
     * @return 按订单分组的待出餐菜品列表
     */
    @Override
    public List<java.util.Map<String, Object>> selectPendingKitchenItemsByOrder(List<String> categoryTypes) {
        return orderMapper.selectPendingKitchenItemsByOrder(categoryTypes);
    }

    /**
     * 标记菜品为已出餐
     *
     * @param id 订单明细ID
     * @return 结果
     */
    @Override
    public int markItemAsServed(Long id) {
        return orderMapper.markItemAsServed(id);
    }

    /**
     * 查询已出餐菜品记录
     *
     * @param params 查询参数（订单号、餐台号、餐品类型、日期范围）
     * @return 已出餐菜品列表
     */
    @Override
    public List<java.util.Map<String, Object>> selectServedKitchenItems(java.util.Map<String, Object> params) {
        return orderMapper.selectServedKitchenItems(params);
    }

    /**
     * 按餐台分组查询出餐记录
     *
     * @param params 查询参数（订单号、餐台号、出餐状态、日期范围）
     * @return 餐台出餐记录列表
     */
    @Override
    public List<java.util.Map<String, Object>> selectKitchenRecordsByTable(java.util.Map<String, Object> params) {
        return orderMapper.selectKitchenRecordsByTable(params);
    }

    /**
     * 查询指定订单的所有菜品明细
     *
     * @param orderId 订单ID
     * @return 菜品明细列表
     */
    @Override
    public List<java.util.Map<String, Object>> selectOrderKitchenDetails(Long orderId) {
        return orderMapper.selectOrderKitchenDetails(orderId);
    }

    /**
     * 生成订单号
     *
     * @return 订单号
     */
    private String generateOrderNumber() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateStr = sdf.format(new Date());
        // 添加3位随机数
        int random = (int) (Math.random() * 900) + 100;
        return "ORD" + dateStr + random;
    }
}

